tooling(pm): name the sweeper's third file in the half-state patrol's adopt list - #15000
Merged
Merged
Conversation
The half-state patrol's documented sibling install listed two files to copy
(`scripts/pm/check-half-states.mjs` and the workflow) while the sweeper has
imported `../invoked-as.mjs` since before that list was written. A repo that
followed it verbatim installed a patrol that cannot start.
Measured on a clean two-file copy of this repo's own files:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module
'.../scripts/invoked-as.mjs' imported from
'.../scripts/pm/check-half-states.mjs'
exit 1
The same copy with `scripts/invoked-as.mjs` added runs the sweeper's
`--self-test` to `2062 cases pass`, exit 0. The failure is loud rather than
silent — the job's final step turns the run red and the anchor is rewritten
with the "THE SWEEP DID NOT RUN" body — but the adopter still gets a dead
patrol, and the next two adopters in the fleet would each get one.
Three comment/wiring corrections, all in the workflow; the sweeper is not
touched, so this repo's sweep behaviour is byte-identical by construction:
- the adopt list names three files, with the measurement that decides it;
- the "No `pnpm install`" note states the sweeper's real import set
(`node:` builtins plus the one repo-local helper) instead of "nothing but
`node:process` and global `fetch`" — that sentence is what an adopter
checks the copy list against, so a stale one re-creates the defect;
- `scripts/invoked-as.mjs` joins the `pull_request` path filter, so a change
to it gets the same pre-merge proof the other two files get. The adopted
objectui copy has carried that row since its port.
Part of #14881
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
os-steve
marked this pull request as ready for review
September 3, 2026 17:23
os-steve
enabled auto-merge
September 3, 2026 17:24
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #14881 — this is the objectstack half of that card. The hotcrm half (the workflow copy, the anchor issue and the repository variable) stays open and is delivered to the PM as an install recipe for the
repo:hotcrmseam card, so this PR deliberately does not carry a closing keyword.What was measured, and what it found
The card asks whether
.github/workflows/half-state-patrol.ymlandscripts/pm/check-half-states.mjsneed any change before the patrol is installed in a sibling repo. The answer is yes, and it is not the change anyone expected: the documented install has been missing a required file.The workflow header's adopt list (step 1) said to copy two files — the sweeper and this workflow. The sweeper's line 897 is:
so it also needs
scripts/invoked-as.mjs. Measured on a clean two-file copy of this repo's own files, in a scratch directory:A repo that followed the list verbatim installed a patrol that cannot start. It fails loudly — the sweep step exits 1, the job's final step turns the run red, and the anchor is rewritten with the "THE SWEEP DID NOT RUN" body — which is the one mercy in it. But the adopter still gets a dead patrol on day one, and the fleet has two more adopters queued behind hotcrm.
The adopted objectui copy already carries the fix on its side: its port added
scripts/invoked-as.mjsto the samepaths:filter, with the note that the sweeper imports the helper and it "was ported alongside". Upstream is catching up to its own port.The three changes, all in the workflow
pnpm install" note states the sweeper's real import set (node:builtinsprocess/child_process/fs/url, globalfetch, plus the one repo-local helper) instead of "nothing butnode:processand globalfetch". The note's conclusion was always right — there is still no npm dependency — but that sentence is exactly what an adopter checks the copy list against, so leaving it stale re-creates the defect one reader later.scripts/invoked-as.mjsjoins thepull_requestpath filter. Named explicitly because it is the one change here that is not a comment: it is a bounded in-place fix of the same defect one layer down. The dependency was undeclared in both places that have to name it, and with the filter as it stood a change to the helper could break the patrol with no PR-time proof running. Scan for the boundary:invoked-as.mjshas exactly one reader underscripts/pm/, the import above; no other workflow filters on it; the row is byte-identical in intent to the objectui copy's.What is NOT changed, and why
scripts/pm/check-half-states.mjsis untouched, so this repo's sweep behaviour is byte-identical by construction rather than by assertion.In particular, no priority-axis parameter was added. hotcrm spells that axis
prio:p0/p1/p2where this repo spells itpriority:p0, and a--priority-prefixknob was the obvious candidate change. It is the wrong one:scripts/pm/ensure-pm-labels.shalready seedspriority:p0into all five fleet repos including hotcrm, and says why in its own comment — "It is in this five-repo loop because that sweep is repo-parameterized (PM_SWEEP_REPO) and grading is a five-repo triage duty". The fleet's declared design is one vocabulary seeded everywhere, not a per-repo dialect in the shared tool; the unusedpriority:p0label object therepo:hotcrmseat found sitting at zero cards in hotcrm is that seeding's own product. Teaching the sweeper a second spelling would be consumer-side tolerance for a producer-side divergence. The coverage gap it leaves is real and is reported on the card instead.Gates
Re-derived after the final commit with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no paths — the script takes its own changeset), which reported 27 runnable families; all 27 were harvested with--commandsand run at5c85a642, all exit 0. Their own verdict lines, quoted:The one substitution, declared: the derivation lists
node scripts/pm/check-half-states.mjsbare, which is the workflow's live sweep against the real board rather than a local gate; it was run in its--self-testform instead.The workflow parses (
yaml.safe_load,pull_request.pathsreads back as the three expected entries).Repo-wide
pnpm lintwas narrowed, and the narrowing is measured rather than asserted: eslint's own accounting for the changed file isFile ignored because no matching configuration was supplied— the flat config supplies no matcher for.yml, so eslint linted 0 of this diff (--format json, one entry, zero errors). The diff touches no JS or TS, and type-aware linting is not enabled, so no untouched file's verdict can move because of it.pnpm linttherefore cannot change in either direction here; CI runs it regardless.skip-changeset: this ships nothing from any released package — a workflow comment plus one path-filter row.Generated by Claude Code
Generated by Claude Code